import { Injectable } from '@nestjs/common';
import { ClsService } from 'nestjs-cls';
import type { ICurrentUser } from '@nbase/shared';

/**
 * 请求上下文 Store 类型
 * 基于 ICurrentUser，添加 ClsStore 要求的索引签名
 */
export interface RequestStore extends Partial<ICurrentUser> {
  [key: symbol]: unknown;  // ClsStore 要求的索引签名
}

/**
 * 请求上下文服务
 * 基于 nestjs-cls (AsyncLocalStorage)
 *
 * 优势：
 * - 高性能：保持单例模式，不会为每个请求创建实例
 * - 异步安全：自动跟踪异步调用链
 * - 类型安全：强类型支持
 */
@Injectable()
export class RequestContextService {
  constructor(private readonly cls: ClsService<RequestStore>) {}

  /**
   * 设置当前用户
   */
  setUser(user: Partial<ICurrentUser>): void {
    this.cls.set('userId', user.userId);
    this.cls.set('username', user.username);
    this.cls.set('roles', user.roles || []);
    this.cls.set('permissions', user.permissions || []);
  }

  /**
   * 获取当前用户 ID
   */
  getCurrentUserId(): string | undefined {
    return this.cls.get('userId');
  }

  /**
   * 获取当前用户名
   */
  getCurrentUsername(): string | undefined {
    return this.cls.get('username');
  }

  /**
   * 获取当前用户角色
   */
  getCurrentUserRoles(): string[] {
    return this.cls.get('roles') || [];
  }

  /**
   * 获取当前用户权限
   */
  getCurrentUserPermissions(): string[] {
    return this.cls.get('permissions') || [];
  }

  /**
   * 获取完整的用户信息
   */
  getUser(): Partial<ICurrentUser> {
    return {
      userId: this.getCurrentUserId(),
      username: this.getCurrentUsername(),
      roles: this.getCurrentUserRoles(),
      permissions: this.getCurrentUserPermissions(),
    };
  }

  /**
   * 检查是否已登录
   */
  isAuthenticated(): boolean {
    return !!this.getCurrentUserId();
  }
}

